home *** CD-ROM | disk | FTP | other *** search
/ Magnum One / Magnum One (Mid-American Digital) (Disc Manufacturing).iso / d12 / ddj0190.arc / ZG_LWLVL.C < prev    next >
C/C++ Source or Header  |  1989-12-19  |  22KB  |  834 lines

  1. /*
  2.     Module:     ZG_LwLvl    (ZipGraph Low-Level functions)
  3.     Version     1.10        01-Nov-1989
  4.  
  5.     Language:   ANSI C w/MS-DOS extensions
  6.     Environ:    IBM-PC compatibles w/MDA, CGA, HGC, EGA, MCGA, or VGA
  7.  
  8.     Compilers:  Borland Turbo C v2.00
  9.                 Lattice C v6.01
  10.                 Microsoft C v5.10 and QuickC v2.01
  11.                 Zortech C & C++ v2.01
  12.  
  13.     Purpose:    Provides low-level graphics routines for detecting graphics
  14.                 adapters, setting graphics modes, and plotting pixels. This
  15.                 module is required by the higher-level ZipGraph modules.
  16.  
  17.     Written by: Scott Robert Ladd
  18.                 705 West Virginia
  19.                 Gunnison CO 81230
  20.  
  21.                 BBS (303)641-6438
  22.                 FidoNet 1:104/708
  23. */
  24.  
  25. #define __ZG_LWLVL_C 1
  26.  
  27. #if !defined(LATTICE)
  28.     #include "conio.h"
  29. #endif
  30.  
  31. #include "dos.h"
  32. #include "zg_lwlvl.h"
  33.  
  34. /*-----------------------------
  35.   handle compiler differences
  36. -----------------------------*/
  37.  
  38. #if defined(_MSC) || defined(_QC) || defined(__ZTC__) || defined(LATTICE)
  39.     #define OUT_PORT(port,val) outp(port,val)
  40. #elif defined(__TURBOC__)
  41.     #define OUT_PORT(port,val) outportb(port,val)
  42. #endif
  43.  
  44. /*--------------------------
  45.   pointer conversion macro
  46. --------------------------*/
  47.  
  48. #if !defined(MK_FP)
  49.     #define MK_FP(seg,off) ((void far *)(((long)(seg) << 16)|(unsigned)(off)))
  50. #endif
  51.  
  52. /*------------------------------
  53.   ZipGraph INTERNAL PROTOTYPES
  54. ------------------------------*/
  55.  
  56. static void DummyPlot(int x, int y, int color);
  57. static int  DummyRead(int x, int y);
  58.  
  59. static void CGA1_Plot(int x, int y, int color);
  60. static void CGA2_Plot(int x, int y, int color);
  61. static void MCGA_Plot(int x, int y, int color);
  62. static void M256_Plot(int x, int y, int color);
  63. static void EVGA_Plot(int x, int y, int color);
  64.  
  65. static int  CGA1_Read(int x, int y);
  66. static int  CGA2_Read(int x, int y);
  67. static int  MCGA_Read(int x, int y);
  68. static int  M256_Read(int x, int y);
  69. static int  EVGA_Read(int x, int y);
  70.  
  71. static void HGC_GraphMode(void);
  72. static void HGC_TextMode(void);
  73. static void HGC_Plot(int x, int y, int color);
  74. static int  HGC_Read(int x, int y);
  75.  
  76. /*---------------------------
  77.   ZipGraph PUBLIC VARIABLES
  78. ---------------------------*/
  79.  
  80. struct
  81.     {
  82.     int     Type;
  83.     int     Monitor;
  84.     int     Mode;
  85.  
  86.     int     Xwidth;
  87.     int     Ylength;
  88.     int     NoColors;
  89.     }
  90.     ZG_VideoInfo;
  91.  
  92. void (* ZG_PlotPixel)(int x, int y, int color) = DummyPlot;
  93. int  (* ZG_ReadPixel)(int x, int y) = DummyRead;
  94.  
  95. /*----------------------------------------
  96.   ZipGraph INTERNAL TABLES and VARIABLES
  97. ----------------------------------------*/
  98.  
  99. static const struct
  100.     {
  101.     int BestRes;
  102.     int MostColor;
  103.  
  104.     unsigned long ModeList;
  105.     }
  106.     VideoTable[06] =
  107.         {
  108.         { 0,                 0,                  0x00000000L},
  109.         { ZG_MOD_640x200x2,  ZG_MOD_320x200x4,   0x00000006L},
  110.         { ZG_MOD_720x348x2,  ZG_MOD_720x348x2,   0x00000001L},
  111.         { ZG_MOD_640x350x16, ZG_MOD_640x350x16,  0x0000007EL},
  112.         { ZG_MOD_640x480x2,  ZG_MOD_320x200x256, 0x00000486L},
  113.         { ZG_MOD_640x480x16, ZG_MOD_320x200x256, 0x000003FEL}
  114.         };
  115.  
  116. static const struct
  117.     {
  118.     char ActualMode;
  119.     void (* PixelProc)(int x, int y, int color);
  120.     int  (* ReadProc)(int x, int y);
  121.     int Xwidth;
  122.     int Ylength;
  123.     int NoColors;
  124.     }
  125.     ModeData[10] =
  126.         {
  127.         { 0x00, HGC_Plot,  HGC_Read,  720, 348, 2  },
  128.         { 0x04, CGA2_Plot, CGA2_Read, 320, 200, 4  },
  129.         { 0x06, CGA1_Plot, CGA1_Read, 640, 200, 2  },
  130.         { 0x0D, MCGA_Plot, MCGA_Read, 320, 200, 16 },
  131.         { 0x0E, EVGA_Plot, EVGA_Read, 640, 200, 16 },
  132.         { 0x0F, EVGA_Plot, EVGA_Read, 640, 350, 4  },
  133.         { 0x10, EVGA_Plot, EVGA_Read, 640, 350, 16 },
  134.         { 0x11, EVGA_Plot, EVGA_Read, 640, 480, 2  },
  135.         { 0x12, EVGA_Plot, EVGA_Read, 640, 480, 16 },
  136.         { 0x13, M256_Plot, M256_Read, 320, 200, 256}
  137.         };
  138.  
  139. static unsigned char OriginalMode = 0;
  140.  
  141. static int PixelMode = ZG_PXL_SET;
  142.  
  143. static int ZG_Inited = 0;
  144.  
  145. /*------------------------------
  146.   IBM-type adapter global data
  147. ------------------------------*/
  148.  
  149. #define CGA_VID_SEG  0xB800
  150. #define EVGA_VID_SEG 0xA000
  151.  
  152. /*-------------------------
  153.   MDA and HGC global data
  154. -------------------------*/
  155.  
  156. /* Hercules video RAM segment */
  157. #define HGC_VID_SEG  0xB000
  158.  
  159. /* Monochrome 6845 Video Controller ports */
  160. #define HGC_IDX_PORT 0x03B4
  161. #define HGC_DAT_PORT 0x03B5
  162. #define HGC_CTL_PORT 0x03B8
  163. #define HGC_CFG_PORT 0x03BF
  164.  
  165. /*----------------------------
  166.   ZipGraph PUBLIC FUNCTIONS!
  167. ----------------------------*/
  168.  
  169. int ZG_Init(void)
  170.     {
  171.     union REGS regs;
  172.     int i, status_changed;
  173.     unsigned char orig_status;
  174.  
  175.     ZG_VideoInfo.Type    = ZG_ERROR;
  176.     ZG_VideoInfo.Monitor = ZG_ERROR;
  177.     ZG_VideoInfo.Mode    = ZG_ERROR;
  178.  
  179.     ZG_VideoInfo.Xwidth   = 0;
  180.     ZG_VideoInfo.Ylength  = 0;
  181.     ZG_VideoInfo.NoColors = 0;
  182.  
  183.     regs.h.ah = 0x1A; /* VGA Identifier Adapter Service */
  184.     regs.h.al = 0;
  185.     int86(0x10,®s,®s);
  186.  
  187.     if (regs.h.al == 0x1A)
  188.         {
  189.         switch (regs.h.bl)
  190.             {
  191.             case 1 : ZG_VideoInfo.Type    = ZG_VID_MDA;
  192.                      ZG_VideoInfo.Monitor = ZG_MTR_MONO;
  193.                      break;
  194.  
  195.             case 2 : ZG_VideoInfo.Type    = ZG_VID_CGA;
  196.                      ZG_VideoInfo.Monitor = ZG_MTR_COLOR;
  197.                      break;
  198.  
  199.             case 4 : ZG_VideoInfo.Type    = ZG_VID_EGA;
  200.                      ZG_VideoInfo.Monitor = ZG_MTR_COLOR;
  201.                      break;
  202.  
  203.             case 5 : ZG_VideoInfo.Type    = ZG_VID_EGA;
  204.                      ZG_VideoInfo.Monitor = ZG_MTR_MONO;
  205.                      break;
  206.  
  207.             case 7 : ZG_VideoInfo.Type    = ZG_VID_VGA;
  208.                      ZG_VideoInfo.Monitor = ZG_MTR_MONO;
  209.                      break;
  210.  
  211.             case 8 : ZG_VideoInfo.Type    = ZG_VID_VGA;
  212.                      ZG_VideoInfo.Monitor = ZG_MTR_COLOR;
  213.                      break;
  214.  
  215.             case 10: ZG_VideoInfo.Type    = ZG_VID_MCGA;
  216.                      ZG_VideoInfo.Monitor = ZG_MTR_COLOR;
  217.                      break;
  218.  
  219.             case 11: ZG_VideoInfo.Type    = ZG_VID_MCGA;
  220.                      ZG_VideoInfo.Monitor = ZG_MTR_MONO;
  221.                      break;
  222.  
  223.             case 12: ZG_VideoInfo.Type    = ZG_VID_MCGA;
  224.                      ZG_VideoInfo.Monitor = ZG_MTR_COLOR;
  225.                      break;
  226.  
  227.             default:
  228.                      return 1;
  229.             }
  230.         }
  231.     else
  232.         {
  233.         /* check for an EGA */
  234.         regs.h.ah = 0x12;
  235.         regs.x.bx = 0x0010;
  236.         int86(0x10,®s,®s);
  237.  
  238.         if (regs.x.bx != 0x10)
  239.             {
  240.             ZG_VideoInfo.Type = ZG_VID_EGA;
  241.  
  242.             regs.h.ah = 0x12;
  243.             regs.x.bx = 0x0010;
  244.             int86(0x10,®s,®s);
  245.  
  246.             if (regs.h.bh == 0)
  247.                 ZG_VideoInfo.Monitor = ZG_MTR_COLOR;
  248.             else
  249.                 ZG_VideoInfo.Monitor = ZG_MTR_MONO;
  250.             }
  251.         else
  252.             {
  253.             int86(0x11,®s,®s);
  254.  
  255.             switch ((regs.h.al & 0x30) >> 4)
  256.                 {
  257.                 case 0 :
  258.                     return 1;
  259.  
  260.                 case 1 :
  261.                 case 2 :
  262.                     ZG_VideoInfo.Type    = ZG_VID_CGA;
  263.                     ZG_VideoInfo.Monitor = ZG_MTR_COLOR;
  264.                     break;
  265.  
  266.                 case 3 :
  267.                     status_changed = 0;
  268.  
  269.                     orig_status = (unsigned char)(inp(0x03BA) & 0x80);
  270.  
  271.                     for (i = 0; (i < 30000) && (!status_changed); ++i)
  272.                         if (orig_status != (unsigned char)(inp(0x03BA) & 0x80))
  273.                             status_changed = 1;
  274.  
  275.                     if (status_changed)
  276.                         ZG_VideoInfo.Type = ZG_VID_HGC;
  277.                     else
  278.                         ZG_VideoInfo.Type = ZG_VID_MDA;
  279.  
  280.                     ZG_VideoInfo.Monitor  = ZG_MTR_MONO;
  281.                 }
  282.             }
  283.         }
  284.  
  285.     if (ZG_VideoInfo.Type != ZG_VID_HGC)
  286.         {
  287.         regs.h.ah = 0x0F;
  288.         int86(0x10,®s,®s);
  289.         OriginalMode = regs.h.al;
  290.         }
  291.  
  292.     ZG_Inited = 1;
  293.  
  294.     return 0;
  295.     }
  296.  
  297. int ZG_SetMode(int VideoMode)
  298.     {
  299.     union REGS regs;
  300.  
  301.     if (VideoMode < 0)
  302.         return 1;
  303.  
  304.     if (VideoMode == ZG_MOD_BESTRES)
  305.         VideoMode = VideoTable[ZG_VideoInfo.Type].BestRes;
  306.     else
  307.         if (VideoMode == ZG_MOD_MOSTCOLOR)
  308.             VideoMode = VideoTable[ZG_VideoInfo.Type].MostColor;
  309.  
  310.     if ((VideoMode > ZG_MOD_320x200x256)
  311.     || (!(VideoTable[ZG_VideoInfo.Type].ModeList & (1 << VideoMode))))
  312.         return 1;
  313.  
  314.     ZG_PlotPixel = ModeData[VideoMode].PixelProc;
  315.     ZG_ReadPixel = ModeData[VideoMode].ReadProc;
  316.  
  317.     if (VideoMode == ZG_MOD_720x348x2)
  318.         HGC_GraphMode();
  319.     else
  320.         {
  321.         regs.h.ah = 0;
  322.         regs.h.al = ModeData[VideoMode].ActualMode;
  323.         int86(0x10,®s,®s);
  324.         }
  325.  
  326.     ZG_VideoInfo.Mode     = VideoMode;
  327.     ZG_VideoInfo.Xwidth   = ModeData[VideoMode].Xwidth;
  328.     ZG_VideoInfo.Ylength  = ModeData[VideoMode].Ylength;
  329.     ZG_VideoInfo.NoColors = ModeData[VideoMode].NoColors;
  330.  
  331.     return 0;
  332.     }
  333.  
  334. int ZG_Done(void)
  335.     {
  336.     union REGS regs;
  337.  
  338.     if (!ZG_Inited)
  339.         return 1;
  340.  
  341.     if (ZG_VideoInfo.Type == ZG_VID_HGC)
  342.         HGC_TextMode();
  343.     else
  344.         {
  345.         regs.h.ah = 0;
  346.         regs.h.al = OriginalMode;
  347.         int86(0x10,®s,®s);
  348.         }
  349.  
  350.     return 0;
  351.     }
  352.  
  353. int ZG_SetPixelMode(int PixMode)
  354.     {
  355.     if ((PixMode < ZG_PXL_SET) || (PixMode > ZG_PXL_XOR))
  356.         return 1;
  357.  
  358.     PixelMode = PixMode;
  359.  
  360.     return 0;
  361.     }
  362.  
  363. int ZG_SetCGAPalette(char PaletteNo)
  364.     {
  365.     union REGS regs;
  366.  
  367.     if (ZG_VideoInfo.Type != ZG_VID_CGA)
  368.         return 1;
  369.  
  370.     regs.h.ah = 0x0B;
  371.     regs.h.bl = PaletteNo;
  372.     regs.h.bh = 0x01;
  373.     int86(0x10,®s,®s);
  374.  
  375.     return 0;
  376.     }
  377.  
  378. int ZG_SetEVGAPalette(char Palette, char Color)
  379.     {
  380.     union REGS regs;
  381.  
  382.     if ((ZG_VideoInfo.Type != ZG_VID_EGA) && (ZG_VideoInfo.Type != ZG_VID_VGA))
  383.         return 1;
  384.  
  385.     regs.h.ah = 0x10;
  386.     regs.h.al = 0x00;
  387.     regs.h.bh = Color;
  388.     regs.h.bl = Palette;
  389.     int86(0x10,®s,®s);
  390.  
  391.     return 0;
  392.     }
  393.  
  394. /*--------------------------------
  395.   Dummy pixel plotter and reader
  396. --------------------------------*/
  397.  
  398. static void DummyPlot(int x, int y, int color)
  399.     {
  400.     /* it does nothing */
  401.     }
  402.  
  403. static int DummyRead(int x, int y)
  404.     {
  405.     /* it does nothing */
  406.     return 0;
  407.     }
  408.  
  409. /*---------------------------------------------
  410.   CGA, EGA, MCGA, VGA pixel plotting functions
  411. ---------------------------------------------*/
  412.  
  413. static void CGA1_Plot(int x, int y, int color)
  414.     {
  415.     /* this routine used for CGA 640x200x2 mode */
  416.     unsigned int pixel_mask;
  417.     unsigned char far * pixel_byte;
  418.  
  419.     /* find the byte containing our pixel */
  420.     pixel_byte = MK_FP(CGA_VID_SEG, 0x2000 * (y&1) + 0x50 * (y/2) + (x >> 3));
  421.  
  422.     /* calculate bit mask */
  423.     pixel_mask = 0x80 >> (x & 7);
  424.  
  425.     /* set pixel */
  426.     switch (PixelMode)
  427.         {
  428.         case ZG_PXL_SET :
  429.             if (color)
  430.                 *pixel_byte |= pixel_mask;
  431.             else
  432.                 *pixel_byte &= ~pixel_mask;
  433.             break;
  434.  
  435.         case ZG_PXL_AND :
  436.             if (color)
  437.                 *pixel_byte &= pixel_mask;
  438.             break;
  439.  
  440.         case ZG_PXL_OR  :
  441.             if (!color)
  442.                 *pixel_byte |= pixel_mask;
  443.             break;
  444.  
  445.         case ZG_PXL_XOR :
  446.             if (!color)
  447.                 *pixel_byte ^= pixel_mask;
  448.         }
  449.     }
  450.  
  451. static void CGA2_Plot(int x, int y, int color)
  452.     {
  453.     /* this routine used for CGA 320x200x4 mode */
  454.     unsigned int pixel_mask, alt_mask;
  455.     unsigned char far * pixel_byte;
  456.  
  457.     /* find the byte containing our pixel */
  458.     pixel_byte = MK_FP(CGA_VID_SEG,0x2000 * (y & 1) + 80 * (y >> 1) + (x >> 2));
  459.     pixel_mask = (color & 3) << (6 - ((x & 3) << 1));
  460.  
  461.     switch (PixelMode)
  462.         {
  463.         case ZG_PXL_SET :
  464.             /* clear the appropriate bits */
  465.             alt_mask     = 0xC0 >> ((x & 3) << 1);
  466.             *pixel_byte &= ~alt_mask;
  467.  
  468.             /* insert the bits for the specified color */
  469.             *pixel_byte |= pixel_mask;
  470.             break;
  471.  
  472.         case ZG_PXL_AND :
  473.             *pixel_byte &= pixel_mask;
  474.             break;
  475.  
  476.         case ZG_PXL_OR :
  477.             *pixel_byte |= pixel_mask;
  478.             break;
  479.  
  480.         case ZG_PXL_XOR :
  481.             *pixel_byte ^= pixel_mask;
  482.         }
  483.     }
  484.  
  485. static void MCGA_Plot(int x, int y, int color)
  486.     {
  487.     /* this routine used for MCGA/VGA 320x200 16-color mode */
  488.     unsigned char pixel_mask;
  489.     volatile unsigned char dummy;
  490.     unsigned char far * pixel_byte;
  491.  
  492.     /* find the byte containing our pixel */
  493.     pixel_byte = MK_FP(EVGA_VID_SEG, (y * 40) + (x >> 3));
  494.  
  495.     /* set up mask */
  496.     pixel_mask = (char)(0x80 >> (x & 7));
  497.  
  498.     /* set-up video controller */
  499.     OUT_PORT(0x03CE, 8);
  500.     OUT_PORT(0x03CF, pixel_mask);
  501.  
  502.     OUT_PORT(0x03CE, 3);
  503.     OUT_PORT(0x03CF, (char)(PixelMode << 3));
  504.  
  505.     OUT_PORT(0x03C4, 2);
  506.     OUT_PORT(0x03C5, 0x0F);
  507.  
  508.     /* do a dummy read to load latches */
  509.     dummy = *pixel_byte;
  510.  
  511.     /* clear latches */
  512.     *pixel_byte = 0;
  513.  
  514.     /* set bit planes */
  515.     OUT_PORT(0x03C4, 2);
  516.     OUT_PORT(0x03C5, (char)color);
  517.  
  518.     *pixel_byte = 0xFF;
  519.  
  520.     /* finish up */
  521.     OUT_PORT(0x03C4, 2);
  522.     OUT_PORT(0x03C5, 0x0F);
  523.  
  524.     OUT_PORT(0x03CE, 3);
  525.     OUT_PORT(0x03CF, 0);
  526.  
  527.     OUT_PORT(0x03CE, 8);
  528.     OUT_PORT(0x03CF, 0xFF);
  529.     }
  530.  
  531. static void M256_Plot(int x, int y, int color)
  532.     {
  533.     /* this routine used for MCGA/VGA 320x200x256 mode */
  534.     unsigned char far * pixel_byte;
  535.  
  536.     /* find the byte containing our pixel */
  537.     pixel_byte = MK_FP(EVGA_VID_SEG, (y << 8) + (y << 6) + x);
  538.  
  539.     /* set pixel */
  540.     switch (PixelMode)
  541.         {
  542.         case ZG_PXL_SET :
  543.             *pixel_byte  = (unsigned char)color;
  544.             break;
  545.         case ZG_PXL_AND :
  546.             *pixel_byte &= (unsigned char)color;
  547.             break;
  548.         case ZG_PXL_OR  :
  549.             *pixel_byte |= (unsigned char)color;
  550.             break;
  551.         case ZG_PXL_XOR :
  552.             *pixel_byte ^= (unsigned char)color;
  553.         }
  554.     }
  555.  
  556. static void EVGA_Plot(int x, int y, int color)
  557.     {
  558.     /* this routine used for all EGA/VGA modes expect 256-color modes */
  559.     unsigned char pixel_mask;
  560.     volatile unsigned char dummy;
  561.     unsigned char far * pixel_byte;
  562.  
  563.     /* find the byte containing our pixel */
  564.     pixel_byte = MK_FP(EVGA_VID_SEG, (y * 80) + (x >> 3));
  565.  
  566.     /* set up mask */
  567.     pixel_mask = (char)(0x80 >> (x & 7));
  568.  
  569.     /* set-up video controller */
  570.     OUT_PORT(0x03CE, 8);
  571.     OUT_PORT(0x03CF, pixel_mask);
  572.  
  573.     OUT_PORT(0x03CE, 3);
  574.     OUT_PORT(0x03CF, (char)(PixelMode << 3));
  575.  
  576.     OUT_PORT(0x03C4, 2);
  577.     OUT_PORT(0x03C5, 0x0F);
  578.  
  579.     /* do a dummy read to load latches */
  580.     dummy = *pixel_byte;
  581.  
  582.     /* clear latches */
  583.     *pixel_byte = 0;
  584.  
  585.     /* set bit planes */
  586.     OUT_PORT(0x03C4, 2);
  587.     OUT_PORT(0x03C5, (char)color);
  588.  
  589.     *pixel_byte = 0xFF;
  590.  
  591.     /* finish up */
  592.     OUT_PORT(0x03C4, 2);
  593.     OUT_PORT(0x03C5, 0x0F);
  594.  
  595.     OUT_PORT(0x03CE, 3);
  596.     OUT_PORT(0x03CF, 0);
  597.  
  598.     OUT_PORT(0x03CE, 8);
  599.     OUT_PORT(0x03CF, 0xFF);
  600.     }
  601.  
  602. /*---------------------------------------------
  603.   CGA, EGA, MCGA, VGA pixel reading functions
  604. ---------------------------------------------*/
  605.  
  606. static int CGA1_Read(int x, int y)
  607.     {
  608.     /* this routine used for CGA 640x200x2 mode */
  609.     unsigned int pixel_mask;
  610.     unsigned char far * pixel_byte;
  611.  
  612.     /* find the byte containing our pixel */
  613.     pixel_byte = MK_FP(CGA_VID_SEG,0x2000 * (y & 3) + 80 * (y >> 1) + (x >> 3));
  614.  
  615.     /* calculate bit mask */
  616.     pixel_mask = 0x80 >> (x & 7);
  617.  
  618.     /* read pixel */
  619.     if (pixel_mask & *pixel_byte)
  620.         return 1;
  621.     else
  622.         return 0;
  623.     }
  624.  
  625. static int CGA2_Read(int x, int y)
  626.     {
  627.     /* this routine used for CGA 320x200x4 mode */
  628.     unsigned int pixel_mask;
  629.     unsigned char far * pixel_byte;
  630.  
  631.     /* find the byte containing our pixel */
  632.     pixel_byte = MK_FP(CGA_VID_SEG,0x2000 * (y & 1) + 80 * (y >> 1) + (x >> 2));
  633.     pixel_mask = 3 << (6 - ((x & 3) << 1));
  634.  
  635.     return (int)((*pixel_byte & pixel_mask) >> (6 - ((x & 3) << 1)));
  636.     }
  637.  
  638. static int MCGA_Read(int x, int y)
  639.     {
  640.     /* this routine used for all EGA/VGA modes expect 256-color modes */
  641.     char i;
  642.     int color = 0;
  643.     unsigned int pixel_mask;
  644.     unsigned char far * pixel_byte;
  645.  
  646.     /* find the byte containing our pixel */
  647.     pixel_byte = MK_FP(EVGA_VID_SEG, (y * 40) + (x >> 3));
  648.  
  649.     /* set up mask */
  650.     pixel_mask = 0x80 >> (x & 7);
  651.  
  652.     /* read the color bits */
  653.     for (i = 0; i < 4; ++i)
  654.         {
  655.         OUT_PORT(0x3CE, 4);
  656.         OUT_PORT(0x3CF, i);
  657.  
  658.         OUT_PORT(0x3CE, 5);
  659.         OUT_PORT(0x3CF, 0);
  660.  
  661.         if (*pixel_byte & pixel_mask)
  662.             color |= 1 << i;
  663.         }
  664.  
  665.     return color;
  666.     }
  667.  
  668. static int M256_Read(int x, int y)
  669.     {
  670.     /* this routine used for MCGA/VGA 320x200x256 mode */
  671.     unsigned char far * pixel_byte;
  672.  
  673.     /* find the byte containing our pixel */
  674.     pixel_byte = MK_FP(EVGA_VID_SEG, (y << 8) + (y << 6) + x);
  675.  
  676.     /* return pixel value */
  677.     return *pixel_byte;
  678.     }
  679.  
  680. static int EVGA_Read(int x, int y)
  681.     {
  682.     /* this routine used for all EGA/VGA modes expect 256-color modes */
  683.     char i;
  684.     int color = 0;
  685.     unsigned int pixel_mask;
  686.     unsigned char far * pixel_byte;
  687.  
  688.     /* find the byte containing our pixel */
  689.     pixel_byte = MK_FP(EVGA_VID_SEG, (y * 80 + (x >> 3)));
  690.  
  691.     /* set up mask */
  692.     pixel_mask = 0x80 >> (x & 7);
  693.  
  694.     /* read the color bits */
  695.     for (i = 0; i < 4; ++i)
  696.         {
  697.         OUT_PORT(0x3CE, 4);
  698.         OUT_PORT(0x3CF, i);
  699.  
  700.         OUT_PORT(0x3CE, 5);
  701.         OUT_PORT(0x3CF, 0);
  702.  
  703.         if (*pixel_byte & pixel_mask)
  704.             color |= 1 << i;
  705.         }
  706.  
  707.     return color;
  708.     }
  709.  
  710. /*---------------
  711.   HGC functions
  712. ---------------*/
  713.  
  714. static void HGC_GraphMode(void)
  715.     {
  716.     /* Codes to be loaded to Hercules 6845 to set graphics mode */
  717.     static const unsigned char HGC_GRAPH_CODES[12] =
  718.         {0x35,0x2D,0x2E,0x07,0x5B,0x02,0x57,0x57,0x02,0x03,0x00,0x00};
  719.  
  720.     unsigned int  i;
  721.     unsigned char far * screen;
  722.  
  723.     OUT_PORT(HGC_CFG_PORT,3);
  724.  
  725.     screen = MK_FP(HGC_VID_SEG,0);
  726.  
  727.     OUT_PORT(HGC_CTL_PORT,2); /* set control port */
  728.  
  729.     for (i = 0; i < sizeof(HGC_GRAPH_CODES); ++i)
  730.         {
  731.         OUT_PORT(HGC_IDX_PORT, (char)i);
  732.         OUT_PORT(HGC_DAT_PORT, HGC_GRAPH_CODES[i]);
  733.         }
  734.  
  735.     for (i = 0; i <= 32767; ++i)
  736.         {
  737.         *screen = '\x00';
  738.         ++screen;
  739.         }
  740.  
  741.     OUT_PORT(HGC_CTL_PORT,10); /* set control port */
  742.     }
  743.  
  744. static void HGC_TextMode(void)
  745.     {
  746.     /* Codes to be loaded to Hercules 6845 to set text mode */
  747.     static const unsigned char HGC_TEXT_CODES[12]  =
  748.         {0x61,0x50,0x52,0x0F,0x19,0x06,0x19,0x19,0x02,0x0D,0x0B,0x0C};
  749.  
  750.     unsigned int  i;
  751.     unsigned char far * screen;
  752.  
  753.     OUT_PORT(HGC_CFG_PORT,3);
  754.  
  755.     screen = MK_FP(HGC_VID_SEG,0);
  756.  
  757.     OUT_PORT(HGC_CTL_PORT,0x20); /* set control port */
  758.  
  759.     for (i = 0; i < sizeof(HGC_TEXT_CODES); ++i)
  760.         {
  761.         OUT_PORT(HGC_IDX_PORT, (char)i);
  762.         OUT_PORT(HGC_DAT_PORT, HGC_TEXT_CODES[i]);
  763.         }
  764.  
  765.     for (i = 0; i <= 32767; ++i)
  766.         {
  767.         if (i % 2 == 1)
  768.             *screen = '\x07';
  769.         else
  770.             *screen = '\x20';
  771.  
  772.         ++screen;
  773.         }
  774.  
  775.     OUT_PORT(HGC_CTL_PORT,0x28); /* set control port */
  776.     }
  777.  
  778. static void HGC_Plot(int x, int y, int color)
  779.     {
  780.     /* this routine used for HGC 720x348x2 mode */
  781.     unsigned int pixel_mask;
  782.     unsigned char far * pixel_byte;
  783.  
  784.     /* find the byte containing our pixel */
  785.     pixel_byte = MK_FP(HGC_VID_SEG,0x2000 * (y & 3) + 90 * (y >> 2) + (x >> 3));
  786.  
  787.     /* calculate bit mask */
  788.     pixel_mask = 0x80 >> (x & 7);
  789.  
  790.     /* set pixel */
  791.     switch (PixelMode)
  792.         {
  793.         case ZG_PXL_SET :
  794.             if (color)
  795.                 *pixel_byte |= pixel_mask;
  796.             else
  797.                 *pixel_byte &= ~pixel_mask;
  798.             break;
  799.  
  800.         case ZG_PXL_AND :
  801.             if (color)
  802.                 *pixel_byte &= pixel_mask;
  803.             break;
  804.  
  805.         case ZG_PXL_OR  :
  806.             if (!color)
  807.                 *pixel_byte |= pixel_mask;
  808.             break;
  809.  
  810.         case ZG_PXL_XOR :
  811.             if (!color)
  812.                 *pixel_byte ^= pixel_mask;
  813.         }
  814.     }
  815.  
  816. static int HGC_Read(int x, int y)
  817.     {
  818.     /* this routine used for HGC 720x348x2 mode */
  819.     unsigned int pixel_mask;
  820.     unsigned char far * pixel_byte;
  821.  
  822.     /* find the byte containing our pixel */
  823.     pixel_byte = MK_FP(HGC_VID_SEG,0x2000 * (y & 3) + 90 * (y >> 2) + (x >> 3));
  824.  
  825.     /* calculate bit mask */
  826.     pixel_mask = 0x80 >> (x & 7);
  827.  
  828.     /* read pixel */
  829.     if (pixel_mask & *pixel_byte)
  830.         return 1;
  831.     else
  832.         return 0;
  833.     }
  834.